抽象 是透過建立一個比原始電腦運作更高階概念層次的「詞彙」,來隱藏複雜性的過程。它讓我們能從 指令式 指令(「要怎麼做」)轉向 宣告式 宣告式意圖(「要做什麼」)。
1. 抽象階梯
隨著我們逐級攀升,我們獲得更高的人類表達力,但也要付出 「抽象稅」:每一層都增加了程式碼與硬體之間的距離,需要更多的機器週期將概念轉譯回基本動作。
2. 參數化邏輯
透過加入一個 步長 參數到我們的 range 函數中,我們將原本靜態的工具演變為彈性引擎。我們可以處理各種方向(正或負的遞增),而無需重寫核心演算法: range(5, 2, -1)。
3. 結果
我們不再使用手動迴圈計數器,而是使用 console.log(sum(range(1, 10)));。這將底層細節封裝在可重用的單元之中。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
What is meant by the 'Abstraction Tax' in software development?
The cost of licensing high-level programming languages.
The increased machine workload caused by translating high-level concepts into primitive actions.
The memory limit imposed by JavaScript on array sizes.
The time spent by developers writing documentation for their abstractions.
✅ Correct!
Every layer of abstraction adds more work for the machine, as it must bridge the gap between human intent and hardware instructions.❌ Incorrect
Think about the performance trade-off discussed: human readability vs. machine performance.QUESTION 2
[Writing Task] Write a range function that takes two arguments, start and end, and returns an array containing all the numbers from start up to (and including) end. Next, write a sum function that takes an array of numbers and returns the sum of these numbers. Run the previous program and see whether it does indeed return 55.
Model Solution: range(1, 10) returns [1..10], sum([1..10]) returns 55.
✅ Correct!
Reference Answer: function range(s, e) { let r = []; for (let i = s; i <= e; i++) r.push(i); return r; } function sum(a) { let t = 0; for (let v of a) t += v; return t; } console.log(sum(range(1, 10))); // 55. Requirement: Output at least 50 words explaining the logic: 'The range function initializes an empty array and uses a for-loop to populate it with integers from the start value to the end value inclusive. The sum function uses a for...of loop to iterate through the resulting array, accumulating values into a total variable which is then returned.'❌ Incorrect
Ensure you are using a loop to build the array and another to reduce it.QUESTION 3
Which approach describes 'Declarative' programming as seen in the slide?
Manually incrementing a pointer in memory.
Describing *what* we want (e.g., sum a range) rather than *how* to manage indices.
Avoiding functions to maximize raw CPU speed.
Writing code exclusively in binary.
✅ Correct!
Declarative code focuses on high-level logic, like using a sum function on a range of data.❌ Incorrect
Declarative programming hides the 'how' behind an abstraction of 'what'.QUESTION 4
[Writing Task] Modify your range function to take an optional third argument that indicates the 'step' value. The call range(1, 10, 2) should return [1, 3, 5, 7, 9]. Make sure it also works with negative step values so that range(5, 2, -1) produces [5, 4, 3, 2].
Model Solution: Handle step by defaulting to 1 (or -1) and adjusting the loop condition.
✅ Correct!
Reference Answer: function range(start, end, step = start < end ? 1 : -1) { let arr = []; if (step > 0) for (let i = start; i <= end; i += step) arr.push(i); else for (let i = start; i >= end; i += step) arr.push(i); return arr; }❌ Incorrect
Don't forget to handle the default step and the negative direction loop check!QUESTION 5
[Short Answer] Let’s try everything we’ve written so far by building up a 5x5 checkerboard.
Model Solution: Use nested loops or an abstracted grid function.
✅ Correct!
Reference Answer: let size = 5; let board = ''; for (let y = 0; y < size; y++) { for (let x = 0; x < size; x++) { if ((x + y) % 2 == 0) board += ' '; else board += '#'; } board += '\n'; } console.log(board);. This uses basic abstraction of grid coordinates (x,y) to determine visual output.❌ Incorrect
Consider using the modulo operator (%) on the sum of x and y indices.Case Study: Refactoring for Clarity
Balancing Expressiveness and Performance
You are working on a data processing module that calculates total revenue from a sequence of transaction IDs. The legacy code uses a 30-line imperative for-loop. You want to refactor it using 'range' and 'sum' abstractions to make it readable for the junior team members.
Q
Identify one risk of using the sum(range(1, 1000000)) abstraction for very large datasets.
Solution:
The primary risk is memory consumption and the 'Abstraction Tax'. The 'range' function creates a physical array containing one million numbers in memory before 'sum' even starts processing them, which can lead to memory exhaustion or garbage collection pauses compared to a single loop that doesn't store the intermediate values.
The primary risk is memory consumption and the 'Abstraction Tax'. The 'range' function creates a physical array containing one million numbers in memory before 'sum' even starts processing them, which can lead to memory exhaustion or garbage collection pauses compared to a single loop that doesn't store the intermediate values.
Q
How does adding a 'step' parameter improve the abstraction's flexibility?
Solution:
Adding a 'step' parameter allows the function to handle non-sequential data (e.g., every second transaction) and reverse-order processing (negative steps) without changing the core function logic, making the code more reusable across different business requirements.
Adding a 'step' parameter allows the function to handle non-sequential data (e.g., every second transaction) and reverse-order processing (negative steps) without changing the core function logic, making the code more reusable across different business requirements.